/**
 * 数据中台-权限管理-默认权限管理
 */
import React from 'react';
import 'antd/dist/antd.css';
import {Card, Col, Input, Row, Tree} from 'antd';
import Container from "@icedesign/container";
import styles from './index.module.scss';
import {Button, Drawer, Form, Icon, Input as NextInput, Message, Pagination, Dialog, Table} from "@alifd/next";
import ZgDialog from "../../../components/ZgDialog";
import event from '@/request'
import $http from '@/service/Services';
import {numberChinese, recursionReset} from "../../../common";
import PipeTree from "../../../components/PipeTree";

const {TreeNode} = Tree;
const {Search} = Input;

const FormItem = Form.Item;


const formItemLayout = {
    labelCol: {
        span: 6
    },
    wrapperCol: {
        span: 14
    }
};
const layout = {
    labelCol: {
        span: 4
    },
    wrapperCol: {
        span: 20
    },
}

/**
 * list
 */
class ServerManage extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            ServerManageDrawerShow: false,
            ServerManageAdd: false,
            ServerManageDrawerValue: {
                parentId: "",
                id: "",
                name: "",
                host: "",
                port: "",
                userName: "",
                password: "",
                remark: ""
            },
            directoryConfig: {
                data: {},
                visible: false,
                title: "删除文件夹",
                content: "删除后将不能恢复，您确认要删除当前文件夹吗？"
            },
            //文件夹的属性结构
            postDirectoryValue: {},
            data: [],
            directoryDrawerValue: {},
            currentDirectoryId: "",
            expandedKeys: [], //展开的key值
            autoExpandParent: true,
            checkedKeys: [], //选中的key,
            searchValue: '',
            searchTreeKey: [] //搜索得key
        };
        // 当前页数
        this.pageNum = 1;
        // 分页每页显示数据条数
        this.pageSize = 10;
        // 数据总条数
        this.totalNum = 0;
        this.$http = $http;
    }

    /**
     * 加载进来的时候执行
     */
    componentDidMount() {
        this.expandedKeysFn();
        this.setState({
            data: this.addParentKeyWrapper(this.state.data) //调用添加父元素key
        })
    }

    /**
     * 在渲染前调用,在客户端也在服务端
     */
    componentWillMount = () => {
        this.getDirectoryTree();
    };

    /**
     * 获取分页的数据
     */
    getServerManagePage = (pageNum) => {
        const _this = this;
        _this.pageNum = typeof (pageNum) == 'number' ? pageNum : _this.pageNum;
        let urls = event.event.url + '/v1/webshellSystemInfo/getWebshellSystemInfoPage';
        this.$http.post(urls,
            {
                pageSize: _this.pageSize,
                pageNum: _this.pageNum,
                condition: {
                    name: _this.state.condition,
                    parentId: _this.state.parentId,
                }
            })
            .then(function (response) {
                const {data} = response;
                const mockData = data.data.voList;
                _this.totalNum = data.data.total;
                mockData.forEach((o, i) => {
                    o.number = i + 1;
                });

                _this.setState({
                    mockData: mockData,
                    config: {
                        data: null,
                        visible: false,
                        title: "",
                        content: ""
                    }
                });
            })
            .catch(function (error) {
                Message.error(error.message);
            })
    };

    /**
     * 条件
     * @param e
     * @param value
     */
    searchCondition = (value, e) => {
        this.setState({
            condition: value,
            config: {
                data: null,
                visible: false,
                title: '',
                content: ''
            }
        });
        this.pageNum = 1;
    };
    /**
     * 改变页面
     * @param currentPage
     */
    onPageChange = (currentPage) => {
        this.state = {
            current: currentPage,
            mockData: this.props.mockData,
            config: {
                data: null,
                visible: false,
                title: '',
                content: ''
            }
        };
        this.getServerManagePage();
    };
    /**
     * 分页大小改变执行
     * @param pageSize
     */
    onPageSizeChange =(pageSize)=>{
        this.pageSize = pageSize;
        this.pageNum = 1;
        this.getServerManagePage();
    };
    /**
     * 修改分页数据
     * @param currentPage
     */
    onChangePage = (currentPage) => {
        this.setState({
            loading: true,
            config: {
                data: null,
                visible: false,
                title: '',
                content: ''
            }
        });
        setTimeout(() => {
            this.getServerManagePage(currentPage);
            this.setState({
                loading: false,
                config: {
                    data: null,
                    visible: false,
                    title: '',
                    content: ''
                }
            });
        }, 0);
    };

    /********************** 目录 *******************************/
    /**
     * 获取数据
     */
    getDirectoryTree = () => {
        const that = this;
        let url = event.event.url + '/v1/webshellDirectory/getDirectoryTree';
        this.$http.get(url)
            .then(function (response) {
                const {data} = response;
                const arr = data.data, dataArr = that.expandedArr(arr, that);
                const expandedKeys = arr.map(o => {
                    return o.id;
                });
                if (arr && arr.length > 0) {
                    that.getServerManagePage();
                }
                that.setState({
                    data: dataArr,
                    expandedKeys: expandedKeys
                })
            })
            .catch(function (error) {
                console.error(error);
                Message.error(error.message);
            })

    };

    /**
     * 删除目录
     */
    deleteDirectory = (item) => {
        this.setState({
                directoryConfig: {
                    data: item,
                    visible: true,
                    title: "删除文件夹",
                    content: "删除后将不能恢复，您确认要删除当前文件夹吗？"
                }
            }
        )
    };

    /**
     * 确定提示弹框
     */
    onOkDialog = () => {
        this.onCloseDialog();
        const _this = this;
        const {data} = this.state.directoryConfig;
        let urls = event.event.url + '/v1/webshellDirectory/deleteDirectoryTree/' + data.key;
        this.$http.post(urls)
            .then(function (response) {
                _this.getDirectoryTree();
            })
            .catch(function (error) {
                Message.error(error.message);
            })
    };
    /**
     * 取消提示弹框
     */
    onCloseDialog = reason => {
        this.setState({
                directoryConfig: {
                    data: {},
                    visible: false,
                    title: "删除文件夹",
                    content: "删除后将不能恢复，您确认要删除当前文件夹吗？"
                }
            }
        )
    };

    /**
     * 添加目录
     */
    addDirectory = (item) => {
        this.editDirectory(item, true);
    };

    /**
     * 修改目录
     */
    editDirectory = (item, add) => {
        this.setState({
            directoryDrawerShow: true,
            directoryAdd: add,
            directoryDrawerValue: {
                parentId: add ? item.key : item.parentId,
                id: add ? "" : item.key,
                name: add ? "" : item.title
            },
        })
    };


    /**
     * 抽屉关闭调用
     */
    onCloseDirectory = () => {
        this.setState({
            directoryDrawerShow: false,
            directoryAdd: false,
            directoryDrawerValue: {
                level: "",
                parentId: "",
                id: "",
                name: "",
                remarks: ""
            }
        });
    };

    /**
     * 提交文件夹的相关数据
     * @param value 表单的值
     * @param e 2021年6月9日00:45:35
     */
    submitDirectory = (value, e) => {
        if (e == null) {
            const that = this;
            const item = {
                ...value,
                description: value.remarks,
            };
            let url = event.event.url + '/v1/webshellDirectory/addOrUpdateDirectoryTree';
            this.$http.post(url, item)
                .then(function (response) {
                    that.onCloseDirectory();
                    that.getDirectoryTree();
                })
                .catch(function (error) {
                    Message.error(error.message);
                })
        }
    };

    /**
     * 展开
     * @param expandedKeys
     */
    onExpand = expandedKeys => {
        this.setState({
            expandedKeys,
            autoExpandParent: false
        });
    };

    /**
     * 展开数据
     * @param arr
     */
    expandedArr = (arr) => {
        function expanded(arrays) {
            const a = [], len = arrays.length;
            if (len === 0) {
                return [];
            }
            for (let i = 0; i < len; i++) {
                const item = arrays[i];
                a.push({
                    parentId: item.parentId,
                    title: item.title,
                    key: item.key,
                    children: expanded(item.children ? item.children : [])
                })
            }
            return a;
        }

        return expanded(arr ? arr : []);
    };
    /**
     * 点击数
     * @param checkedKeys
     */
    onCheck = (checkedKeys) => {
        this.setState({checkedKeys})
    };
    /**
     * 选中数的事件
     * @param ks
     */
    onSelected = (ks) => {
        if (ks && ks.length > 0) {
            this.setState({
                parentId: ks[0]
            }, () => {
                this.getServerManagePage();
            })
        }
    };

    /********************** 目录 *******************************/
    /********************** 主机 *******************************/
    /**
     * 条件
     * @param e
     * @param value
     */
    searchCondition = (value, e) => {
        this.setState({
            condition: value,
            config: {
                data: null,
                visible: false,
                title: "",
                content: ""
            }
        });
        this.pageNum = 1;
    };
    /**
     * 服务编辑
     * @param record
     */
    toServerUpdate = record => {
        this.setState({
            ServerManageDrawerShow: true,
            ServerManageAdd: true,
            ServerManageDrawerValue: {
                parentId: record.currentDirectoryId,
                id: record.id,
                name: record.name,
                host: record.host,
                port: record.port,
                userName: record.userName,
                password: "",
                remark: record.remark
            }
        });
    };

    /**
     * 删除记录的弹框
     * @param record
     */
    toServerDelete = record => {
        this.setState({
            postConfig: {
                data: record,
                visible: true,
                title: "是否真的要删除当前服务？",
                content: ""
            },
        });
    };

    /**
     * 远程操作
     * @param record
     */
    toServerSSH = record => {
        window.open(
            window.location.origin +
            "/#" +
            `/webShell/ssh?id=` + record.id + "&name=" + record.name
        );
    };
    /**
     * 关闭服务器的信息
     */
    onCloseServerManage = () => {
        this.setState({
            ServerManageDrawerShow: false,
            ServerManageAdd: false,
            ServerManageDrawerValue: {
                parentId: "",
                id: "",
                name: "",
                host: "",
                port: "",
                userName: "",
                password: "",
                remark: ""
            }
        })
    }
    /**
     * 新建服务
     * 抽屉关闭调用
     */
    addServerManage = () => {
        this.setState({
            ServerManageDrawerShow: true,
            ServerManageAdd: true,
            ServerManageDrawerValue: {
                parentId: this.state.currentDirectoryId,
                id: "",
                name: "",
                host: this.state.level,
                port: "",
                userName: "",
                password: "",
                remark: ""
            }
        });
    };

    /**
     * 提交文件夹的相关数据
     * @param value 表单的值
     * @param e 2021年6月9日00:45:35
     */
    submitServerManage = (value, e) => {
        if (e == null) {
            const that = this;
            const item = {
                ...value
            };
            item.parentId = this.state.parentId;
            let url = event.event.url + '/v1/webshellSystemInfo/saveOrUpdateSystemInfo';
            this.$http.post(url, item)
                .then(function (response) {
                    that.setState({
                        ServerManageDrawerShow: false,
                        ServerManageAdd: false,
                        ServerManageDrawerValue: {
                            parentId: "",
                            id: "",
                            name: "",
                            host: "",
                            port: "",
                            userName: "",
                            password: "",
                            remark: ""
                        }
                    }, () => {
                        that.getServerManagePage();
                    });
                })
                .catch(function (error) {
                    Message.error(error.message);
                })
        }
        console.log(e);
    };

    /********************************** 主机服务 *************************/

    /**
     * search变化
     * @param e
     */
    onChange = (e) => {
        const {value} = e.target;
        const dataList = [];
        if (value) {
            const generateList = data => { //tree树片扁平化
                for (let i = 0; i < data.length; i++) {
                    const node = data[i];
                    const {key, title, parent_key} = node;
                    dataList.push({key, title: title, parent_key: parent_key}); //根据自己的数据更换parent_key代表父级key
                    if (node.children) {
                        generateList(node.children);
                    }
                }
            };
            generateList(this.state.data);

            const getParentKey = (key, tree) => { //获取父元素可以
                let parentKey;
                for (let i = 0; i < tree.length; i++) {
                    const node = tree[i];
                    if (node.children) {
                        if (node.children.some(item => item.key === key)) {
                            parentKey = node.key;
                        } else if (getParentKey(key, node.children)) {
                            parentKey = getParentKey(key, node.children);
                        }
                    }
                }
                return parentKey;
            };

            const expandedKeys = dataList
                .map(item => {
                    if (item.title.indexOf(value) > -1) {
                        return getParentKey(item.key, this.state.data);
                    }
                    return null;
                })
                .filter((item, i, self) => item && self.indexOf(item) === i);

            this.setState({
                expandedKeys: expandedKeys,
                searchValue: value,
                autoExpandParent: true
            })
        } else {
            this.expandedKeysFn();//重置展开key
            this.setState({
                searchValue: value,
                autoExpandParent: true
            })
        }
    };
    /**
     * 给子级添加父级Key
     * @param tree
     * @returns {any}
     */
    addParentKeyWrapper = (tree) => {
        //深度克隆
        const data = JSON.parse(JSON.stringify(tree));

        function addParentKey(data, parentKey) {
            data.forEach(ele => {
                const {children, key} = ele;
                ele.parent_key = parentKey;
                if (children) {//如果唯一标识不是code可以自行改变
                    addParentKey(children, key)
                }
            })
        }

        addParentKey(data, null); //一开始为null,根节点没有父级
        return data;
    };
    /**
     * 生成树结构函数
     * @param data
     * @returns {*}
     */
    renderTreeNode = (data) => {
        if (data.length === 0) {
            return
        }
        let {searchValue} = this.state;
        return data.map((item) => {
            const index = item.title.indexOf(searchValue);
            const beforeStr = item.title.substr(0, index);
            const afterStr = item.title.substr(index + searchValue.length);
            const title =
                index > -1 ? (
                    <div style={{}}>
                        <div style={{display: 'inline-block', width: '70%', padding: '8px 8px;'}}>
                            {beforeStr}
                            <span style={{color: "red"}}>{searchValue}</span>
                            {afterStr}
                        </div>
                        <div style={{display: 'inline-block', width: '30%', textAlign: 'right'}}>

                            {
                                [0].map(o => {
                                    if (item.parentId !== null && (!item.children || item.children.length === 0)) {
                                        return (
                                            <Icon type="minus" title={"删除"} onClick={() => {
                                                this.deleteDirectory(item)
                                            }} size={'xs'} style={{paddingRight: '10px'}}/>
                                        )
                                    }
                                })
                            }
                            <Icon type="add" title={"添加"} onClick={() => {
                                this.addDirectory(item)
                            }} size={'xs'} style={{paddingRight: '10px'}}/>

                            <Icon type="edit" title={"编辑"} onClick={() => {
                                this.editDirectory(item, false)
                            }} size={'xs'} style={{paddingRight: '10px'}}/>
                        </div>
                    </div>

                ) : (
                    <div>
                        <span>{item.title}</span>
                    </div>
                );
            if (item.children && item.children.length > 0) {
                return <TreeNode title={title} key={item.key}>
                    {
                        this.renderTreeNode(item.children)
                    }
                </TreeNode>
            }
            return <TreeNode key={item.key} title={title}></TreeNode>
        })
    }
    /**
     * 展开函数
     */
    expandedKeysFn = () => {
        let {data} = this.state;
        let arr = [];
        let loop = (data) => {
            data.map((item, index) => {
                arr.push(item.key);
                if (item.children && item.children.length > 0) {
                    loop(item.children)
                }
            })
        };
        loop(data);
        this.setState({
            expandedKeys: arr
        })
    };

    render() {
        const {
            expandedKeys,
            autoExpandParent,
            checkedKeys,
            data,
            mockData
        } = this.state;
        return (
            <div>
                <Drawer
                    title="目录"
                    closeMode={['close', 'esc', 'mask']}
                    visible={this.state.directoryDrawerShow}
                    width={550}
                    onClose={this.onCloseDepart}
                >
                    <Form {...formItemLayout}>

                        <FormItem
                            hidden={true}
                        >
                            <NextInput
                                id="parentId"
                                name="parentId"
                                defaultValue={this.state.directoryDrawerValue.parentId}
                                aria-required="true"/>
                        </FormItem>
                        <FormItem
                            hidden={true}
                        >
                            <NextInput
                                id="id"
                                name="id"
                                defaultValue={this.state.directoryDrawerValue.id}
                                aria-required="true"/>
                        </FormItem>


                        <FormItem

                            required
                            requiredMessage={"名称不能为空"}
                            label="名称："
                        >
                            <NextInput
                                id="name"
                                name="name"
                                defaultValue={this.state.directoryDrawerValue.name}
                                aria-required="true"/>
                        </FormItem>
                        <FormItem wrapperCol={{offset: 6}}>
                            <Form.Submit
                                validate
                                type="primary"
                                onClick={(v, e) => this.submitDirectory(v, e)}
                                style={{marginRight: 10}}
                            >
                                提交
                            </Form.Submit>
                            <Form.Reset>重置</Form.Reset>
                        </FormItem>
                    </Form>
                </Drawer>
                <Drawer
                    title="主机管理"
                    closeMode={['close', 'esc', 'mask']}
                    visible={this.state.ServerManageDrawerShow}
                    width={550}
                    placement={this.state.placement}
                    onClose={this.onCloseServerManage}
                >
                    <Form {...formItemLayout}>

                        <FormItem
                            hidden={true}
                        >
                            <NextInput
                                id="parentId"
                                name="parentId"
                                defaultValue={this.state.ServerManageDrawerValue.parentId}
                                aria-required="true"/>
                        </FormItem>
                        <FormItem
                            hidden={true}
                        >
                            <NextInput
                                id="id"
                                name="id"
                                defaultValue={this.state.ServerManageDrawerValue.id}
                                aria-required="true"/>
                        </FormItem>


                        <FormItem
                            required
                            requiredMessage={"名称不能为空"}
                            label="主机名称："
                        >
                            <NextInput
                                id="name"
                                name="name"
                                defaultValue={this.state.ServerManageDrawerValue.name}
                                aria-required="true"/>
                        </FormItem>


                        <FormItem
                            required
                            requiredMessage={"主机地址不能为空"}
                            label="主机地址："
                        >
                            <NextInput
                                id="host"
                                name="host"
                                defaultValue={this.state.ServerManageDrawerValue.host}
                                aria-required="true"/>
                        </FormItem>

                        <FormItem
                            required
                            requiredMessage={"主机端口不能为空"}
                            label="主机端口："
                        >
                            <NextInput
                                id="port"
                                name="port"
                                defaultValue={this.state.ServerManageDrawerValue.port}
                                aria-required="true"/>
                        </FormItem>
                        <FormItem
                            required
                            requiredMessage={"用户名不能为空"}
                            label="用户名："
                        >
                            <NextInput
                                id="userName"
                                name="userName"
                                defaultValue={this.state.ServerManageDrawerValue.userName}
                                aria-required="true"/>
                        </FormItem>
                        <FormItem
                            hidden={this.state.ServerManageDrawerValue.id != null && this.state.ServerManageDrawerValue.id != ''}
                            required={this.state.ServerManageDrawerValue.id == null || this.state.ServerManageDrawerValue.id == ''}
                            requiredMessage={"密码不能为空" + this.state.ServerManageDrawerValue.id}
                            label="密码："
                        >
                            <NextInput
                                id="password"
                                name="password"
                                defaultValue={this.state.ServerManageDrawerValue.password}
                                aria-required="true"/>
                        </FormItem>

                        <FormItem
                            label="岗位描述："
                        >
                            <NextInput.TextArea id="remark"
                                                name="remark"
                                                defaultValue={this.state.ServerManageDrawerValue.remark}
                                                placeholder="描述"/>
                        </FormItem>
                        <FormItem wrapperCol={{offset: 6}}>
                            <Form.Submit
                                validate
                                type="primary"
                                onClick={(v, e) => this.submitServerManage(v, e)}
                                style={{marginRight: 10}}
                            >
                                提交
                            </Form.Submit>
                            <Form.Reset>重置</Form.Reset>
                        </FormItem>
                    </Form>
                </Drawer>
                <div className='container-header'>
                    <p>主机管理</p>
                </div>
                <Container className='container-main'>
                    <Row>
                        <Col span={18} push={6}>
                            <Card

                                bordered={false}
                                style={{minHeight: 360}}
                                className="depart_detail"
                            >
                                <div className={styles.codeBox}>
                                    <Container className='container-main'>
                                        <div className='container-btnBox' style={{marginTop: '0'}}>
                                            <div className={styles.buttons}>
                                                <Button onClick={() => this.addServerManage()}
                                                        className='pipe-btn-add'>新建服务</Button>
                                                <span className={styles.caseNumber}>
                                <Input onChange={this.searchCondition.bind(this)}
                                       hasClear
                                       placeholder="请输入服务名称/主机"
                                       className={`${styles.input} ${styles.shortInput}`}/>
                                <Button
                                    type="primary"
                                    className='pipe-btn-search'
                                    onClick={this.getServerManagePage}
                                >
                                查询
                                </Button>
                            </span>
                                            </div>
                                        </div>
                                        <div className='container-table'>
                                            <Table dataSource={mockData} primaryKey="id" className={styles.table}>
                                                <Table.Column align="center" title="序号" dataIndex="number"/>
                                                <Table.Column align="center" title="名称" dataIndex="name"/>
                                                <Table.Column align="center" title="主机" dataIndex="host"/>
                                                <Table.Column align="center" title="端口" dataIndex="port"/>
                                                <Table.Column align="center" title="用户名" dataIndex="userName"/>
                                                <Table.Column align="center" title="密码" dataIndex="password"/>
                                                <Table.Column align="center" title="操作" width={350} cell={
                                                    (value, index, record) => {
                                                        return (
                                                            <div>
                                                                <Button size="small" type="primary" text
                                                                        className='pipe-btn-edit'
                                                                        onClick={() => {
                                                                            this.toServerUpdate(record)
                                                                        }}>编辑服务</Button>
                                                                <Button size="small" type="primary" text
                                                                        className='pipe-btn-edit'
                                                                        onClick={() => this.toServerSSH(record)}>远程操作</Button>
                                                                <Button size="small" type="primary" text
                                                                        className='pipe-btn-delete'
                                                                        onClick={() => this.toServerDelete(record)}>删除服务</Button>

                                                            </div>
                                                        )

                                                    }
                                                }/>
                                            </Table>
                                            <Pagination defaultCurrent={1}
                                                        pageSize={this.pageSize}
                                                        total={this.totalNum}
                                                        onChange={this.onChangePage}
                                                        onPageSizeChange={this.onPageSizeChange}
                                                        pageSizeList={[5,10,20,50,100,200]}
                                                        pageSizeSelector="dropdown"
                                                        className="page-demo"
                                                        size="small"
                                            />
                                        </div>
                                    </Container>
                                </div>
                            </Card>

                        </Col>
                        <Col span={6} pull={18}>
                            <div className={styles.treeDev}>
                                <div className={styles.codeBox}>
                                    <Search style={{marginBottom: 8}} placeholder="Search" onChange={this.onChange}/>
                                    <Tree
                                        blockNode
                                        expandedKeys={expandedKeys} //默认展开的key
                                        onExpand={this.onExpand} //展开事件
                                        autoExpandParent={autoExpandParent} //是否自动展开父节点
                                        checkedKeys={checkedKeys} //选中的key
                                        defaultExpandAll={true} //默认展开所有
                                        onCheck={this.onCheck} //选中事件
                                        onSelect={this.onSelected} //选中的状态
                                    >
                                        {this.renderTreeNode(data)}
                                    </Tree>
                                </div>
                            </div>
                        </Col>
                    </Row>
                </Container>
                <Dialog
                    className='pipe-dialog'
                    title="提示信息"
                    visible={this.state.directoryConfig.visible}
                    onOk={this.onOkDialog}
                    onCancel={this.onCloseDialog.bind(this, 'cancelClick')}
                    onClose={this.onCloseDialog}>
                    删除后不能恢复，确认要删除？
                </Dialog>
            </div>
        )
            ;
    }
}

export default ServerManage;
